use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::ops::Deref;
use std::rc::Rc;
use chrono::Local;
use serde::{Deserialize, Serialize};
use yew::{Callback, Reducible};
use yew_hooks::{UseWebSocketHandle};
use yewdux::Dispatch;
use crate::business::page::fragment::im_session_list_view::{SessionAction, SessionListState};
use crate::business::rpc::router::message_router::{receive_message, receive_read_message};
use crate::business::rpc::router::ping_router::do_ping;
use crate::business::websocket::dto::common_dto::{ExceptionResp, OkListResp, OkResp};
use crate::business::websocket::dto::im_base_dto::{CollectItemList, ConfigItemList, FeedbackItemList, LabelInfoItemList, ModuleInfoItemList, SensitiveWordItemList};
use crate::business::websocket::dto::im_department_dto::DepartmentInfoItemList;
use crate::business::websocket::dto::im_group_dto::{GroupInfoItem, GroupInfoItemList};
use crate::business::websocket::dto::im_message_dto::{MessageActionList, MessageObject, MessageObjectList, MessageReadReq};
use crate::business::websocket::dto::im_session_dto::SessionItemList;
use crate::db::pojo::pojo::ImMessage;
use crate::business::websocket::local_seq::LocalSeq;
use crate::business::websocket::send_data_router::{RpcRequest, RpcResponse};
use crate::business::websocket::dto::ping_dto::{PingReq, PongResp};
use crate::business::websocket::dto::rpc_data::{decode_to_data, parse_to_header, ReceiveDataParse, RpcData, RpcHeader};
use crate::business::websocket::dto::user_dto::{LoginResp, UserInfoItemList};

pub struct ImReceiveSendHandle {
    use_web_socket_handle: Rc<RefCell<Option<UseWebSocketHandle>>>,  // 发送消息
    pub(crate) action_message_callback: Rc<RefCell<Callback<ImReceiveSendActionMessage>>>,  // 接受消息就调用此方法
    send_data_set: Rc<RefCell<HashSet<String>>>, // 发送消息的local_seq列表
    receive_data_set: Rc<RefCell<HashSet<String>>>, // 接受消息的local_seq列表
    local_seq: Rc<RefCell<Option<LocalSeq>>>,  // local_seq 生成器
    session: Rc<RefCell<HashMap<String, String>>>, // session 的HashMap
    send_callback: Rc<RefCell<HashMap::<String, Callback<RpcResponse>>>>, // 消息发送列表
    tmp_seq: Rc<RefCell<u64>>,
    login_user_id: Option<String>,
    session_list_dispatch: Dispatch<SessionListState>,
}

pub enum ImReceiveSendHandleMsg {
    Request(RpcRequest, Callback<RpcResponse>),  // 发送消息事件
    ActionMessageCallback(Callback<ImReceiveSendActionMessage>),    // 消息回显事件
    RemoveMessageCallback,                       // 去掉消息回显事件
    SendData(String),                            // 发送回执信息
    LoginSuccess(RpcData<LoginResp>),            // 登录成功事件
    Ping(PingReq),                               //
    ReceiveMessage(String),

    SetUseWebSocketHandle(UseWebSocketHandle),
}

#[derive(Debug, Clone)]
pub enum ImReceiveSendActionMessage {
    Show(Vec<ImMessage>),
    Update(Vec<ImMessage>),
}

impl Reducible for ImReceiveSendHandle {
    type Action = ImReceiveSendHandleMsg;

    fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
        match action {
            ImReceiveSendHandleMsg::Request(rpc_request, cb) => {
                log::info!("sending rpc_request");
                rpc_request.send_data2(&self, cb);
            },
            ImReceiveSendHandleMsg::ActionMessageCallback(callback) => {
                log::info!("show message callback");
                // let mut smc = self.show_message_callback.borrow_mut();
                // smc.replace(callback);
                return Self{
                    use_web_socket_handle: self.use_web_socket_handle.clone(),
                    action_message_callback: Rc::new(RefCell::new(callback)),
                    send_data_set: self.send_data_set.clone(),
                    receive_data_set: self.receive_data_set.clone(),
                    local_seq: self.local_seq.clone(),
                    session: self.session.clone(),
                    send_callback: self.send_callback.clone(),
                    tmp_seq: self.tmp_seq.clone(),
                    login_user_id: self.login_user_id.clone(),
                    session_list_dispatch: self.session_list_dispatch.clone(),
                }.into()
            },
            ImReceiveSendHandleMsg::RemoveMessageCallback => {
                log::info!("null message callback");
                // let mut mut_call =self.show_message_callback.borrow_mut();
                // * mut_call = None;
                return Self{
                    use_web_socket_handle: self.use_web_socket_handle.clone(),
                    action_message_callback: self.action_message_callback.clone(),
                    send_data_set: self.send_data_set.clone(),
                    receive_data_set: self.receive_data_set.clone(),
                    local_seq: self.local_seq.clone(),
                    session: self.session.clone(),
                    send_callback: self.send_callback.clone(),
                    tmp_seq: self.tmp_seq.clone(),
                    login_user_id: self.login_user_id.clone(),
                    session_list_dispatch: self.session_list_dispatch.clone(),
                }.into()
            },
            ImReceiveSendHandleMsg::SendData(data) => {
                self.send(data);
            },
            ImReceiveSendHandleMsg:: LoginSuccess(rpc_data)=> {
                let local_seq = rpc_data.local_seq();
                let login_result = rpc_data.data.unwrap();
                log::info!("set local seq, {:?}, {}", login_result, local_seq);

                if let Ok(login_resp) = login_result {
                    let login_user_id = login_resp.user_id.clone();
                    self.login_success(&login_resp);

                    let mut smc = self.local_seq.borrow_mut();
                    smc.replace(LocalSeq::new(&login_resp.success_data_time));

                    let mut callback_map = self.send_callback.borrow_mut();
                    log::info!("callback map5: {:?}", callback_map);
                    let callback = callback_map.remove(&local_seq);
                    log::info!("set local seq get callback result, {:?}", callback.is_some());
                    if let Some(cb) = callback {
                        log::info!("set local seq emit callback");
                        cb.emit(RpcResponse::LoginResponse(Ok(login_resp)));
                    }

                    log::info!("login success_user_id: {:?}", login_user_id);
                    return Self{
                        use_web_socket_handle: self.use_web_socket_handle.clone(),
                        action_message_callback: self.action_message_callback.clone(),
                        send_data_set: self.send_data_set.clone(),
                        receive_data_set: self.receive_data_set.clone(),
                        local_seq: self.local_seq.clone(),
                        session: self.session.clone(),
                        send_callback: self.send_callback.clone(),
                        tmp_seq: self.tmp_seq.clone(),
                        login_user_id: Some(login_user_id),
                        session_list_dispatch: self.session_list_dispatch.clone(),
                    }.into()
                }
            },
            ImReceiveSendHandleMsg::Ping(_ping_req) => {

            }
            ImReceiveSendHandleMsg::ReceiveMessage(msg) => {
                log::info!("websocket response, {}", msg);
                let (rpc_header, data) = parse_to_header(msg);
                let _path = &rpc_header.path;

                log::info!("received data, data: {:?}", rpc_header);

                let version = rpc_header.version;
                let local_seq = rpc_header.local_seq();
                if version != 0 {
                    let mut send_data_set = self.send_data_set.borrow_mut().clone();
                    let existed = send_data_set.remove(&local_seq);
                    log::info!("send data success: {:?}, is removed: {}", local_seq, existed);
                } else {
                    let mut t = self.receive_data_set.borrow_mut().clone();
                    log::info!("received data1111");
                    t.insert(local_seq);
                    log::info!("received data44444");
                }

                log::info!("send data set size: {}, receive data set size: {}", self.send_data_set.borrow_mut().len(), self.receive_data_set.borrow_mut().len());
                let handle = self.do_receive_data(rpc_header, data);

                if handle.is_some() {
                    return Rc::new(handle.unwrap());
                }
            }
            ImReceiveSendHandleMsg::SetUseWebSocketHandle(handle) => {
                log::info!("websocket set use web  socket handle");
                let uh = self.use_web_socket_handle.clone();
                let mut hh = uh.borrow_mut();
                hh.replace(handle);
                let ttt = Rc::new(Self{
                    use_web_socket_handle: uh.clone(),
                    action_message_callback: self.action_message_callback.clone(),
                    send_data_set: self.send_data_set.clone(),
                    receive_data_set: self.receive_data_set.clone(),
                    local_seq: self.local_seq.clone(),
                    session: self.session.clone(),
                    send_callback: self.send_callback.clone(),
                    tmp_seq: self.tmp_seq.clone(),
                    login_user_id: self.login_user_id.clone(),
                    session_list_dispatch: self.session_list_dispatch.clone(),
                });

                return ttt;
            }
        }
        self
    }
}

impl PartialEq for ImReceiveSendHandle {
    fn eq(&self, _other: &Self) -> bool {
        true
    }
}

impl Clone for ImReceiveSendHandle {
    fn clone(&self) -> Self {
        Self {
            use_web_socket_handle: self.use_web_socket_handle.clone(),
            action_message_callback: self.action_message_callback.clone(),
            send_data_set: self.send_data_set.clone(),
            receive_data_set: self.receive_data_set.clone(),
            local_seq: self.local_seq.clone(),
            session: self.session.clone(),
            send_callback: self.send_callback.clone(),
            tmp_seq: self.tmp_seq.clone(),
            login_user_id: self.login_user_id.clone(),
            session_list_dispatch: self.session_list_dispatch.clone(),
        }
    }
}

impl ImReceiveSendHandle {
    pub fn new(session_list_dispatch: Dispatch<SessionListState>)->Self{
        let _session_list_dispatch_clone = session_list_dispatch.clone();
        Self{
            use_web_socket_handle: Rc::new(RefCell::new(None)),
            action_message_callback: Rc::new(RefCell::new(Callback::from(move |_action_message| {} ))),
            send_data_set: Rc::new(RefCell::new(HashSet::new())),
            receive_data_set: Rc::new(RefCell::new(HashSet::new())),
            local_seq: Rc::new(RefCell::new(None)),
            session: Rc::new(RefCell::new(HashMap::new())),
            send_callback: Rc::new(RefCell::new(HashMap::new())),
            tmp_seq: Rc::new(RefCell::new(0)),
            login_user_id: None,
            session_list_dispatch,
        }
    }

    pub fn send_data<T: Serialize + for<'de> Deserialize<'de> + 'static>(&self, path: String, data: T, cb: Callback<RpcResponse>) {
        let mut rpc_data = RpcData::new(path, data, self.increase_local_seq());
        let local_seq = rpc_data.local_seq();

        let session = self.session.borrow();
        log::info!("rpc session: {:?}", session);
        let auth_code = session.get("authCode");
        if let Some(auth_code) = auth_code {
            rpc_data.ext_data_map.insert("authCode".to_owned(), auth_code.to_owned());
        }

        self.cache_send_data_local_seq(local_seq.clone());

        let json: String = rpc_data.into();
        log::info!("websocket request: {}", json);

        self.send_data_to_server(&json);

        let mut callback_map = self.send_callback.borrow_mut();
        callback_map.insert(local_seq.clone(), cb);
        log::info!("callback map: {:?}", callback_map);
    }
}



impl ImReceiveSendHandle {
    fn do_receive_data(&self, rpc_header: RpcHeader, data: String) -> Option<ImReceiveSendHandle> {
        let path = rpc_header.path.clone();
        log::info!("do router: {:?}", path);
        match rpc_header.path.as_str() {
            "pingToClient" => {
                let ping_req = decode_to_data(&rpc_header, data);
                let local_seq = rpc_header.local_seq();
                match ping_req {
                    Ok(ping_req) => {
                        let result = do_ping(ping_req);
                        self.do_response(path, local_seq, result);
                    }
                    Err(exc) => {
                        self.do_response_exception(path, local_seq, exc);
                    }
                }
            }
            "serverMessage" => {
                let receive_data : Result<MessageObject, ExceptionResp> = decode_to_data(&rpc_header, data);
                let local_seq = rpc_header.local_seq();
                match receive_data {
                    Ok(message_object) => {
                        let user_id = self.login_user_id.clone().unwrap();
                        let result = receive_message(self.session_list_dispatch.clone(), self.action_message_callback.clone(), user_id, message_object);
                        self.do_response(path, local_seq, result);
                    }
                    Err(exc) => {
                        self.do_response_exception(path, local_seq, exc);
                    }
                }
            }
            "serverReadMessage" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<MessageReadReq, ExceptionResp> = decode_to_data(&rpc_header, data);
                match receive_data {
                    Ok(message_read_req) => {
                        let user_id = self.login_user_id.clone().unwrap();
                        let result = receive_read_message(self.action_message_callback.clone(), user_id, message_read_req);
                        self.do_response(path, local_seq, result);
                    }
                    Err(exc) => {
                        self.do_response_exception(path, local_seq, exc);
                    }
                }
            }
            "login" => {
                let receive_data : Result<LoginResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                return self.callback_login_resp(&rpc_header, receive_data);
            },
            "reconnection" => {
                let receive_data : Result<LoginResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                return self.callback_login_resp(&rpc_header, receive_data);
            }
            "loginByToken" => {
                let receive_data : Result<LoginResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                return self.callback_login_resp(&rpc_header, receive_data);
            }
            "pingToServer" => {
                // do nothing
            }
            "pullConfigs" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<ConfigItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullConfigsResponse(receive_data));
            }
            "pullDepartments" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<DepartmentInfoItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullDepartmentsResponse(receive_data));
            }
            "pullUsers" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<UserInfoItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullUsersResponse(receive_data));
            }
            "pullGroups" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<GroupInfoItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullGroupsResponse(receive_data));
            }
            "pullModules" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<ModuleInfoItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullModulesResponse(receive_data));
            }
            "pullSessions" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<SessionItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullSessionsResponse(receive_data));
            }
            "pullMessageBySessionIds" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<MessageObjectList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullMessageBySessionIdsResponse(receive_data));
            }
            "pullMessageByServerIds" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<MessageObjectList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullMessageByServerIdsResponse(receive_data));
            }
            "okMessages" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::OkMessagesResponse(receive_data));
            }
            "pullActionMessages" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<MessageActionList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullMessageActionResponse(receive_data));
            }
            "okPullActionMessages" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::OkMessageActionResponse(receive_data));
            }
            "pullLabels" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<LabelInfoItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullLabesResponse(receive_data));
            }
            "pullCollects" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<CollectItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullCollectsResponse(receive_data));
            }
            "pullFeedbacks"=> {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<FeedbackItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullFeedbacksResponse(receive_data));
            }
            "pullSensitiveWords" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<SensitiveWordItemList, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::PullSensitiveWordsResponse(receive_data));
            }

            "imMessage" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::SendMessageResponse(receive_data));
            }
            "imMessages" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkListResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::SendMessagesResponse(receive_data));
            }
            "readMessages" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::ReadMessageResponse(receive_data));
            }
            "withdrawMessages" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::WithdrawMessageResponse(receive_data));
            }
            "groupCreate" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::GroupCreateResponse(receive_data));
            }
            "groupAdd" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<OkResp, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::GroupAddResponse(receive_data));
            }
            "groupInfo" => {
                let local_seq = rpc_header.local_seq();
                let receive_data : Result<GroupInfoItem, ExceptionResp> = decode_to_data(&rpc_header, data);
                self.callback_resp(local_seq, RpcResponse::GroupPullInfoResponse(receive_data));
            }
            _ => {
                log::error!("unknown router (error): {:?}", path);
            }
        }
        None
    }

    fn send(&self, content: String) {
        log::info!("sending data333, {}", content);
        let t1 = self.use_web_socket_handle.borrow_mut().clone();
        let t2 = t1.unwrap().ws.clone();
        let websocket = t2.borrow_mut().clone().unwrap();
        websocket.send_with_str(&content).expect("TODO: panic message");
        log::info!("sending data, end");
    }
    
    fn callback_login_resp(&self, rpc_header: &RpcHeader, receive_data: Result<LoginResp, ExceptionResp>)-> Option<ImReceiveSendHandle> {
        let local_seq = rpc_header.local_seq();
        log::info!("set local seq, {:?}, {}", receive_data, local_seq);

        if let Ok(login_resp) = receive_data {
            let mut smc = self.local_seq.borrow_mut();
            smc.replace(LocalSeq::new(&login_resp.success_data_time));

            self.login_success(&login_resp);

            let login_user_id = login_resp.user_id.clone();

            let ss = self.session.borrow();
            log::info!("login success, session: {:?}", ss);

            let mut callback_map = self.send_callback.borrow_mut();
            log::info!("callback map2: {:?}", callback_map);
            let callback = callback_map.remove(&local_seq);
            log::info!("set local seq get callback result, {:?}", callback.is_some());
            if let Some(cb) = callback {
                log::info!("set local seq emit callback");
                cb.emit(RpcResponse::LoginResponse(Ok(login_resp)));
            }

            return Some(ImReceiveSendHandle {
                use_web_socket_handle: self.use_web_socket_handle.clone(),
                action_message_callback: self.action_message_callback.clone(),
                send_data_set: self.send_data_set.clone(),
                receive_data_set: self.receive_data_set.clone(),
                local_seq: self.local_seq.clone(),
                session: self.session.clone(),
                send_callback: self.send_callback.clone(),
                tmp_seq: self.tmp_seq.clone(),
                login_user_id: Some(login_user_id),
                session_list_dispatch: self.session_list_dispatch.clone(),
            })
        }
        None
    }

    fn callback_resp(&self, local_seq: String, rpc_response: RpcResponse) {
        let mut callback_map = self.send_callback.borrow_mut();
        log::info!("callback map2: {:?}", callback_map);
        let callback = callback_map.remove(&local_seq);
        log::info!("set local seq get callback result, {:?}", callback.is_some());
        if let Some(cb) = callback {
            log::info!("set local seq emit callback");
            cb.emit(rpc_response);
        }
    }

    fn login_success(&self, login_resp: &LoginResp) {
        log::info!("router login success: {:?}", login_resp);
        let mut session = self.session.borrow_mut();
        session.insert("authCode".to_string(), login_resp.auth_code.to_string());
        session.insert("AUTH_TOKEN".to_string(), login_resp.auth_token.clone());
        session.insert("TENANT_ID".to_string(), login_resp.tenant_code.clone());
        session.insert("LOGIN_USER_ID".to_string(), login_resp.user_id.clone());
        log::info!("router login success2: {:?}", session);
    }

    fn increase_local_seq(&self)->String {
        if let Some(mut cb) = self.local_seq.borrow_mut().take() {
            cb.increase().to_string()
        } else {
            format!("{}_{}", Local::now().timestamp(), self.increase_tmp_seq())
        }
    }

    fn increase_tmp_seq(&self)->u64 {
        let mut mut_seq = self.tmp_seq.borrow_mut();
        *mut_seq += 1;
        mut_seq.deref().clone()
    }

    fn cache_send_data_local_seq(&self, local_seq: String) {
        let rsd = self.clone();
        let mut send_data_set = rsd.send_data_set.borrow_mut();
        send_data_set.insert(local_seq);
        log::info!("send data set size: {}", send_data_set.len());
    }

    fn send_data_to_server(&self, json_str: &String) {
        let use_web_socket_handle = self.use_web_socket_handle.clone();
        if let Some(use_web_socket_handle) = use_web_socket_handle.borrow().as_ref() {
            let t1 = use_web_socket_handle.ws.clone();
            if let Some(websocket) = t1.borrow_mut().as_ref() {
                log::info!("websocket send data2: {}", json_str);
                websocket.send_with_str(json_str).expect("TODO: panic message");
            } else {
                log::error!("websocket send error");
            }
        } else {
            log::error!("no websocket handle");
        }
    }

    fn do_response<T: Serialize + for<'de> Deserialize<'de> + 'static>(&self, path: String, local_seq: String, result: Result<T, ExceptionResp>) {
        match result {
            Ok(resp) => {
                let rpc_data_response = RpcData::response(path, resp, local_seq);
                let response: String = rpc_data_response.into();
                self.send(response);
            }
            Err(exc) => {
                self.do_response_exception(path, local_seq, exc);
            }
        }
    }

    fn do_response_exception(&self, path: String, local_seq: String, result: ExceptionResp) {
        let rpc_data_response = RpcData::response(path, result, local_seq);
        let response: String = rpc_data_response.into();
        self.send(response);
    }

    fn increase_hot_message(session_list_dispatch: Dispatch<SessionListState>, action_message: ImReceiveSendActionMessage) {
        match action_message {
            ImReceiveSendActionMessage::Show(messages) => {
                let map = messages.iter().fold(HashMap::new(), |mut map, message| {
                    *map.entry(message.session_id.clone()).or_insert(0) += 1;
                    map
                });
                session_list_dispatch.apply(SessionAction::IncrementHotMessages(map))
            }
            _ => {}
        }
    }
}

